package com.yricky.jinrishici;

import SimpleXml.Xml;
import SimpleXml.XmlNode;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zhy.http.library.OkHttpUtils;
import com.zhy.http.library.callback.StringCallback;


import java.io.*;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

public class PoetModel {
    public static final String TOKEN="X-User-Token";
    private final File cfgFile;
    private final File nxtFile;
    private final File cacheDir;
    private final File cacheFile;
    private XmlNode xmlNode;
    private final Timer delayTimer;
    private boolean isHttpRequesting=false;
    private PoetModel(File file_){
        this.cfgFile =new File(file_,"config.xml");
        this.nxtFile =new File(file_,"nxt.json");
        this.cacheDir=new File(file_,"cache");
        this.cacheFile=new File(file_,"cache.json");
        xmlNode= Xml.parseXml(YUtils.FileUtils.readFile(cfgFile));
        delayTimer=new Timer();
        if(xmlNode==null){
            xmlNode=XmlNode.EMPTY_NODE("jinrishici");
            xmlNode.setAttr("time","0");
            saveConfig();
        }
    }

    public static PoetModel getModel(File dirFile){
        if (dirFile.isFile()||!dirFile.exists()){
            try {
                YUtils.FileUtils.deleteDir(dirFile.getPath());
                dirFile.mkdirs();
                new File(dirFile,"config.xml").createNewFile();
                new File(dirFile,"cache.json").createNewFile();
                new File(dirFile,"cache").mkdirs();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return new PoetModel(dirFile);
    }

    public String getJSONString(){
        return YUtils.FileUtils.readFile(cacheFile);
    }

    public String getToken(){
        return xmlNode.hasAttr(TOKEN)? xmlNode.getAttr(TOKEN) :null;
    }

    public void update(UpdateCallback updateCallback){
        Date date=new Date();
        if(date.getTime()-getCacheSavedTime()<10000){
            if(updateCallback!=null)updateCallback.onCall("success");
            return;
        }
        if(nxtFile.exists()) {
            cacheFile.delete();
            nxtFile.renameTo(cacheFile);
        }
        if(!isHttpRequesting){
            isHttpRequesting=true;
            if(xmlNode.hasAttr(TOKEN)){
                OkHttpUtils.get().url("https://v2.jinrishici.com/sentence")
                        .addHeader(TOKEN, xmlNode.getAttr(TOKEN))
                        .tag(this)
                        .build().execute(new StringCallback() {
                    @Override
                    public void onError(okhttp3.Call call, Exception e, int i) {
                        releaseHttp();
                        if(updateCallback!=null)
                            updateCallback.onCall(e.toString());
                    }

                    @Override
                    public void onResponse(String s, int i) {
                        saveNxt(s);
                        releaseHttp();
                        if(updateCallback!=null)
                            updateCallback.onCall("success");
                    }
                });
            }else /* get token from server */{
                OkHttpUtils.get().url("https://v2.jinrishici.com/token")
                        .tag(this)
                        .build().execute(new StringCallback() {
                    @Override
                    public void onError(okhttp3.Call call, Exception e, int i) {
                        releaseHttp();
                    }

                    @Override
                    public void onResponse(String s, int i) {
                        JSONObject jsonObject= JSON.parseObject(s);
                        String token=jsonObject.getString("data");
                        xmlNode.setAttr(TOKEN,token);
                        saveConfig();
                        delayTimer.schedule(new TimerTask() {
                            @Override
                            public void run() {
                                isHttpRequesting=false;
                                update(updateCallback);
                            }
                        }, 1000);
                    }
                });
            }
        }
    }

    private void releaseHttp(){
        delayTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                isHttpRequesting = false;
            }
        }, 500);
    }

    private void saveConfig(){
        save(cfgFile,xmlNode.toString());
    }

    private void saveNxt(String s){
        String time=""+ new Date().getTime();
        save(nxtFile, s);

        //
        save(new File(cacheDir,time), s);

        xmlNode.removeAttr("time");
        xmlNode.setAttr("time",time);
        saveConfig();
    }

    private long getCacheSavedTime(){
        return Long.parseLong(xmlNode.getAttr("time"));
    }

    private void save(File aFile,String s){
        try {
            Writer output=new FileWriter(aFile);
            Reader in = new CharArrayReader(s.toCharArray());
            char[] buf = new char[1024];
            int bytesRead;
            while ((bytesRead = in.read(buf)) > 0)
                output.write(buf, 0, bytesRead);
            output.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public interface UpdateCallback{
        void onCall(String status);
    }
}
